﻿using System;
using System.Collections.Generic;
using System.Drawing;
using System.IO;
using System.Linq;
using System.Threading;
using System.Threading.Tasks;
using System.Windows.Forms;
using OpenCvSharp;
using Sdcb.PaddleInference;
using Sdcb.PaddleOCR;
using Sdcb.PaddleOCR.Models;
using Sdcb.PaddleOCR.Models.Local;

namespace RfidCompareWin
{
    /// <summary>
    /// 屏幕OCR识别工具类
    /// </summary>
    public class ScreenOCRTool : IDisposable
    {
        private PaddleOcrAll _ocrEngine;
        private Thread _captureThread;
        private CancellationTokenSource _cancellationTokenSource;
        private bool _isRunning = false;
        private List<string> _interestedTexts = new List<string>();

        // 屏幕捕获相关
        private Rectangle _captureRegion = Screen.PrimaryScreen.Bounds;
        private int _captureInterval = 1000; // 毫秒

        // 事件
        public event EventHandler<OcrResultEventArgs> OcrResultAvailable;
        public event EventHandler<string> ErrorOccurred;

        public ScreenOCRTool()
        {
            // 初始化OCR引擎但不加载模型，等到Start时再加载
        }

        /// <summary>
        /// 设置感兴趣的文本列表
        /// </summary>
        public void SetInterestedTexts(IEnumerable<string> texts)
        {
            _interestedTexts = texts?.ToList() ?? new List<string>();
        }

        /// <summary>
        /// 设置捕获区域
        /// </summary>
        public void SetCaptureRegion(Rectangle region)
        {
            _captureRegion = region;
        }

        /// <summary>
        /// 设置捕获间隔(毫秒)
        /// </summary>
        public void SetCaptureInterval(int interval)
        {
            if (interval <= 0) throw new ArgumentException("Interval must be positive");
            _captureInterval = interval;
        }

        /// <summary>
        /// 开始屏幕OCR识别
        /// </summary>
        public async Task StartAsync()
        {
            if (_isRunning) return;

            try
            {
                // 初始化OCR引擎
                FullOcrModel model = LocalFullModels.ChineseV3;
                _ocrEngine = new PaddleOcrAll(model, PaddleDevice.Mkldnn())
                {
                    AllowRotateDetection = false,
                    Enable180Classification = false
                };

                _isRunning = true;
                _cancellationTokenSource = new CancellationTokenSource();

                // 在后台线程执行OCR
                _captureThread = new Thread(() => CaptureAndOcrLoop(_cancellationTokenSource.Token));
                _captureThread.IsBackground = true;
                _captureThread.Start();
            }
            catch (Exception ex)
            {
                ErrorOccurred?.Invoke(this, $"启动失败: {ex.Message}");
                throw;
            }
        }

        /// <summary>
        /// 停止OCR识别
        /// </summary>
        public void Stop()
        {
            if (!_isRunning) return;

            _isRunning = false;
            _cancellationTokenSource?.Cancel();
            _captureThread?.Join(1000);

            _ocrEngine?.Dispose();
            _ocrEngine = null;
        }

        /// <summary>
        /// 屏幕捕获和OCR识别循环
        /// </summary>
        private void CaptureAndOcrLoop(CancellationToken cancellationToken)
        {
            try
            {
                while (!cancellationToken.IsCancellationRequested)
                {
                    try
                    {
                        // 捕获屏幕
                        using var screenBitmap = CaptureScreen();
                        using var mat = BitmapToMat(screenBitmap);

                        // 执行OCR
                        var result = _ocrEngine.Run(mat);

                        // 筛选感兴趣的文本
                        var filteredRegions = FilterRegionsByInterestedTexts(result);

                        // 触发事件
                        OcrResultAvailable?.Invoke(this, new OcrResultEventArgs
                        {
                            AllTexts = result.Text,
                            InterestedRegions = filteredRegions
                        });
                    }
                    catch (Exception ex)
                    {
                        ErrorOccurred?.Invoke(this, $"识别过程中出错: {ex.Message}");
                    }

                    // 等待指定间隔
                    Thread.Sleep(_captureInterval);
                }
            }
            catch (Exception ex)
            {
                ErrorOccurred?.Invoke(this, $"OCR线程异常: {ex.Message}");
            }
        }

        /// <summary>
        /// 捕获屏幕
        /// </summary>
        private Bitmap CaptureScreen()
        {
            Bitmap bitmap = new Bitmap(_captureRegion.Width, _captureRegion.Height);
            using (Graphics g = Graphics.FromImage(bitmap))
            {
                g.CopyFromScreen(_captureRegion.Location, System.Drawing.Point.Empty, _captureRegion.Size);
            }
            return bitmap;
        }

        /// <summary>
        /// 将Bitmap转换为OpenCV的Mat
        /// </summary>
        private Mat BitmapToMat(Bitmap bitmap)
        {
            using var memoryStream = new MemoryStream();
            bitmap.Save(memoryStream, System.Drawing.Imaging.ImageFormat.Bmp);
            byte[] byteArray = memoryStream.ToArray();
            return Cv2.ImDecode(byteArray, ImreadModes.Color);
        }

        /// <summary>
        /// 根据感兴趣的文本筛选结果区域
        /// </summary>
        private List<PaddleOcrResultRegion> FilterRegionsByInterestedTexts(PaddleOcrResult result)
        {
            if (_interestedTexts == null || !_interestedTexts.Any())
            {
                return result.Regions.ToList();
            }

            return result.Regions
                .Where(r => _interestedTexts.Any(text => r.Text.Contains(text)))
                .ToList();
        }

        /// <summary>
        /// 实现IDisposable接口
        /// </summary>
        public void Dispose()
        {
            Stop();
            GC.SuppressFinalize(this);
        }
    }

    /// <summary>
    /// OCR结果事件参数
    /// </summary>
    public class OcrResultEventArgs : EventArgs
    {
        public string AllTexts { get; set; }
        public List<PaddleOcrResultRegion> InterestedRegions { get; set; }
    }
}